<?php

class Utility_FormatFunctions {

    const ROUNDING_CEILING = 'ceiling';
    
    static public function format_value($str_type, $mix, $arr_data = array(), $arr_options = array()) {

        $str = $mix;

        if(is_null($str)) {
            return null;
        }

        switch($str_type) {
        case 'number':
            $str = self::format_number($mix, $arr_data, $arr_options);
            break;
        case 'currency':
            $str = self::format_currency($mix, $arr_data, $arr_options);
            break;
        case 'percentage':
            $str = self::format_percentage($mix, $arr_data, $arr_options);
            break;
        case 'date':
            $str = self::format_date($mix, $arr_data, $arr_options);
            break;
        case 'age':
            $str = self::format_age($mix, $arr_data, $arr_options);
            break;
        case 'boolean':
            $str = self::format_boolean($mix, $arr_data, $arr_options);
            break;
        case 'seconds':
            $str = self::format_seconds($mix, $arr_data, $arr_options);
            break;
        case 'enumeration':
            $str = self::format_enumeration($mix, $arr_data, $arr_options);
            break;
        case 'timestamp':
            $str = self::format_timestamp($mix, $arr_data, $arr_options);
            break;
        case 'link':
            $str = self::format_link($mix, $arr_data, $arr_options);
            break;
        case 'list':
            $str = self::format_list($mix, $arr_data, $arr_options);
            break;
        case 'checkbox':
            $str = self::format_checkbox($mix, $arr_data, $arr_options);
            break;
        case 'custom':
            $str = self::format_custom($mix, $arr_data, $arr_options);
            break;
        case 'count':
            $str = self::format_count($mix, $arr_data, $arr_options);
            break;
        }

        return $str;
    }

    static public function format_number($mix, $arr_data = array(), $arr_options = array()) {

        $int_precision = isset($arr_options['precision']) ? (int) $arr_options['precision'] : 0;

        $str = null;
        if(is_numeric($mix)) {

            if(isset($arr_options['scale'])) {
                $mix = $mix * $arr_options['scale'];
            }
            
            if(isset($arr_options['rounding'])) {
                $enm_rounding = $arr_options['rounding'];
                $mix = round($mix, $int_precision, $enm_rounding);
            }
            
            if(isset($arr_options['ceiling']) && ($arr_options['ceiling'])) {
                $mix = ceil($mix);
            }
            
            if(isset($arr_options['floor']) && ($arr_options['floor'])) {
                $mix = floor($mix);
            }

            $str = number_format($mix, $int_precision);
        } else {
            $str = $mix;
        }

        return $str;

    }

    static public function format_percentage($mix, $arr_data = array(), $arr_options = array()) {

        $str = self::format_number($mix, $arr_data, $arr_options);

        $str_percent = isset($arr_options['percentage']) ? $arr_options['percentage'] : '%';

        return $str . $str_percent;
    }
    
    static public function format_enumeration($mix, $arr_data = array(), $arr_options = array()) {

        $str = $mix;
        if(isset($arr_options['key_value_map'])) {
            $arr_map = $arr_options['key_value_map'];
            if(is_array($arr_map) && isset($arr_map[$str])) {
                $str = $arr_map[$str];
            }
        }

        return $str;
    }

    static public function format_currency($mix, $arr_data = array(), $arr_options = array()) {

        $str_value = self::format_number($mix, $arr_data, $arr_options);

        $str_currency = isset($arr_options['currency']) ? $arr_options['currency'] : '£';
        $str_key = isset($arr_options['currency_key']) ? $arr_options['currency_key'] : null;
        if(isset($arr_data[$str_key])) {
            $str_currency = $arr_data[$str_key];
        }

        $str_template = isset($arr_options['template']) ? $arr_options['template'] : '{currency} {value}';

        $str = str_replace(array('{value}', '{currency}'), array($str_value, $str_currency), $str_template);

        return $str;
    }

    static public function format_date($mix, $arr_data = array(), $arr_options = array()) {

        $str_format = isset($arr_options['format']) ? $arr_options['format'] : 'Y-m-d';

        $str_date_formatted = $mix;

        $str_year = substr($mix, 0, 4);
        $str_year_twodigit = substr($mix, 2, 2);

        $str_year_placeholder = '2000';

        $str_date_fake = str_replace($str_year, $str_year_placeholder, $mix);
        $int_date_fake = strtotime($str_date_fake);

        if($int_date_fake) {
            $str_format_fullyear = str_replace('y', 'Y', $str_format);
            $str_date_formatted = date($str_format_fullyear, $int_date_fake);
            $str_replace = (strpos($str_format, 'Y') !== false) ? $str_year : $str_year_twodigit;
            $str_date_formatted = str_replace($str_year_placeholder, $str_replace, $str_date_formatted);
        }

        return $str_date_formatted;

    }

    static public function format_age($mix, $arr_data = array(), $arr_options = array()) {

        $int_now  = strtotime('now');
        $int_then = strtotime($mix);
        
        $int_age = $int_now - $int_then;
        
        $str_age = $int_age . ' seconds';
        if($int_age >= 86400) {
            $int = round($int_age / 86400);
            $str_units = ($int == 1) ? 'day' : 'days';
            $str_age = $int . ' ' . $str_units;
        } else if(($int_age < 86400) && ($int_age >= 3600)) {
            $int = round($int_age / 3600);
            $str_units = ($int == 1) ? 'hour' : 'hours';
            $str_age = $int . ' ' . $str_units;
        } else if(($int_age < 3600) && ($int_age >= 60)) {
            $int = round($int_age / 60);
            $str_units = ($int == 1) ? 'minute' : 'minutes';
            $str_age = $int . ' ' . $str_units;
        } else if($int_age < 60) {
            $str_age = $int_age . ' seconds';
        }
        
        return $str_age;

    }

    static public function format_boolean($mix, $arr_data = array(), $arr_options = array()) {

        $str_true = isset($arr_options['true']) ? $arr_options['true'] : 'Yes';
        $str_false = isset($arr_options['false']) ? $arr_options['false'] : 'No';

        $bln = (boolean) $mix;

        return $bln ? $str_true : $str_false;

    }

    static public function format_seconds($mix, $arr_data = array(), $arr_options = array()) {

        return Utility_DateFunctions::secs_to_hours_mins_secs($mix);

    }

    static public function format_timestamp($mix, $arr_data = array(), $arr_options = array()) {

        $str_format = isset($arr_options['format']) ? $arr_options['format'] : 'Y-m-d H:i:s';
        return date($str_format, $mix);

    }

    static public function format_bytes($mix, $arr_data = array(), $arr_options = array()) {

        $int_precision = isset($arr_options['precision']) ? (int) $arr_options['precision'] : 2;

        $str = null;
        if(is_numeric($mix)) {

            $arr_units = array('B', 'KB', 'MB', 'GB', 'TB');

            $int_bytes = max($mix, 0);
            $pow = floor(($int_bytes ? log($int_bytes) : 0) / log(1024));
            $pow = min($pow, count($arr_units) - 1);

            $int_bytes /= pow(1024, $pow);

            $str = number_format($int_bytes, $int_precision) . ' ' . $arr_units[$pow];

        } else {
            $str = $mix;
        }

        return $str;

    }
    
    static public function format_link($mix, $arr_data = array(), $arr_options = array()) {

        $str_label = $mix;
        if(isset($arr_options['label_source'])) {
            $str_label_key = $arr_options['label_source'];
            $str_label = isset($arr_data[$str_label_key]) ? $arr_data[$str_label_key] : null;
        } else if(isset($arr_options['label'])) {
            $str_label = $arr_options['label'];
        }
        
        return '<a href="' . $mix . '">' . $str_label . '</a>';
        
    }
    
    static public function format_list($mix, $arr_data = array(), $arr_options = array()) {

        if(is_string($mix)) {
            if(isset($arr_options['exploder'])) {
                $mix = explode($arr_options['exploder'], $mix);
            }
        }
        
        $arr = (array) $mix;
        
        if(isset($arr_options['use_keys']) && ($arr_options['use_keys'] === true)) {
            $arr = array_keys($arr);
        }
        
        $str_delimiter = isset($arr_options['delimiter']) ? $arr_options['delimiter'] : ', ';
        
        return implode($str_delimiter, $arr);
        
    }
    
    static public function format_checkbox($mix, $arr_data = array(), $arr_options = array()) {

        $str_name = isset($arr_options['input_name']) ? $arr_options['input_name'] : 'selector[]';
        
        $str_value = $mix;
        
        $str_id = str_replace('[]', '', $str_name . '-' . $str_value);
        
        $str_disabled = '';
        if(isset($arr_options['input_disabled_source'])) {
            if(isset($arr_data[$arr_options['input_disabled_source']])) {
                $bln = $arr_data[$arr_options['input_disabled_source']];
                if($bln) {
                    $str_disabled = ' disabled="disabled"';
                }
            }
        }
        
        
        return '<input type="checkbox" name="' . $str_name . '" id="' . $str_id . '" value="' . $str_value . '"' . $str_disabled . '/>';
        
    }
    
    static public function format_custom($mix, $arr_data = array(), $arr_options = array()) {

        $str_return = null;
        
        $clb_handler = isset($arr_options['callback']) ? $arr_options['callback'] : null;
        if(is_callable($clb_handler)) {
            
            $str_return = (string) call_user_func($clb_handler, $mix, $arr_data, $arr_options);
        }
        
        return $str_return;
    }

    static public function format_count($mix, $arr_data = array(), $arr_options = array()) {

        $str_return = null;

        if (is_array($mix)) {
            $str_return = self::format_number(count($mix), $arr_data, $arr_options);
        }

        return $str_return;
    }

}
